<template>
	<view class="model">
		<canvas
		  v-if="thumb"
		  type="webgl"
		  id="webgl"
		  bindtouchstart="touchStart"
		  bindtouchmove="touchMove"
		  bindtouchend="touchEnd"
		></canvas>
		<view class="loading" v-if="schedule<100">
			<u-loading-icon></u-loading-icon>
			<text>{{schedule}}%</text>
		</view>
	</view>
</template>

<script>
	import {createScopedThreejs} from 'threejs-miniprogram'
	import { registerGLTFLoader } from '@/loaders/gltf-loader.js';
	var camera, scene, renderer,ob;
	var requestAnimationFrame; // 动画回调函数
	export default {
		props:{
			thumb:{
				type:String,
				default:()=>{
					return ''
				},
			},
			model:{
				type:String,
				// default:'http://192.168.50.107:18082/download/132.glb',
				default:'https://pro.jrxtiejin.com/index/o/132.glb',
			}
		},
		data() {
			return {
				schedule:0,
				animationId:null
			}
		},
		onReady() {
			// this.modelInit()
		},
		methods: {
			modelInit(){
				let that = this;
				const query = uni.createSelectorQuery().in(this);
				query.select('#webgl').node().exec((res) => {
					console.log('[res]',res)
					var canvas = res[0].node;
					// 设置背景透明
					var gl = canvas.getContext('webgl', {
						alpha: true
					});
					if (canvas != undefined) {
						//  canvas.width 和canvas.style都需要设置，否则无法显示渲染
						canvas.width = canvas._width;
						canvas.height = canvas._height;
						requestAnimationFrame = canvas.requestAnimationFrame;
						that.init(canvas);
					}
				})
			},
			init(canvas){
				try {
				    const res = uni.getSystemInfoSync();
				    console.log(res.pixelRatio);
					var devicePixelRatio = res.pixelRatio
				} catch (e) {
				    // error
				}
				console.log('[开始加载模型]')
			    const THREE = createScopedThreejs(canvas)
			    registerGLTFLoader(THREE)
			    //设置相机
			    camera = new THREE.PerspectiveCamera(50, canvas.width / canvas.height, 0.25, 100);
			    camera.position.set(-2,0, 9);
			    camera.lookAt(new THREE.Vector3(0, 0, 0));
				//获取场景对象
			    scene = new THREE.Scene();
			    //设置光线
				//获取渲染器对象
				renderer = new THREE.WebGLRenderer({ 
					antialias: true,
					logarithmicDepthBuffer: true,
				});
				//设置渲染区域宽高
				renderer.setSize(canvas.width, canvas.height);
				renderer.setPixelRatio (devicePixelRatio)
			    var light = new THREE.DirectionalLight(0xffffff);
			    light.position.set(10, 10, 50);
			    scene.add(light);
				ob = new THREE.Object3D() // 创建一个ob类
				if(this.thumb){
					var textureLoader = new THREE.TextureLoader() ;
					// 定义物体的几何结构
					var sphereGeometry = new THREE.BoxBufferGeometry(5,5,0.2);
					// 定义物体的材质
					var sphereMaterial = [
						//下标0：右面材质
						new THREE.MeshBasicMaterial({
						    color: '#222423',
						    // wireframe: true,
							opacity:0,
							transparent:true
						}),
						//下标1：左面材质
						new THREE.MeshBasicMaterial({
						    color: '#222423',
						    wireframe: true,
							opacity:0,
							transparent:true
						}),
						//下标2：上面材质
						new THREE.MeshBasicMaterial({
						    color: '#222423',
						    wireframe: true,
							opacity:0,
							transparent:true
						}),
						//下标3：下面材质
						new THREE.MeshBasicMaterial({
						    color: '#222423',
						    wireframe: true,
							opacity:0,
							transparent:true
						}),
						//下标4：前面材质
						new THREE.MeshBasicMaterial({
						    map: textureLoader.load(this.thumb)
						}),
						//下标5：后面材质
						new THREE.MeshBasicMaterial({
						    map: textureLoader.load('https://pro.jrxtiejin.com/index/o/backimgs.png')
						}),
					]
					// 用刚才定义的几何结构和材质来创建物体
					let sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
					ob.add(sphere)
					// 定位中心的位置
					// sphere.position.set(0,0,0);		
					// 添加到场景中
					// scene.add(sphere);
				}
				const manager = new THREE.LoadingManager();
				manager.onProgress = ( item, loaded, total )=> {
					console.log( '[进度]',item,(loaded / total * 100 ) + '% loaded' );
					this.schedule = loaded / total * 100 
				};
			    //加载外部模型
			    var loader = new THREE.GLTFLoader(manager);
			    loader.load(this.model, (gltf)=> {
					let model = gltf.scene;
					let box = new THREE.Box3().setFromObject(model);
					// 缩放
					model.scale.set(1, 1, 2.5);
					if(this.thumb){
						let childModel = gltf.scene.children[0]

						// 设置环境贴图，反射周围环境，渲染更逼真
						var textureCube = new THREE.CubeTextureLoader()
						.setPath('../static/images/')
						.load(['back.jpg', 'dipan.png', 'back.jpg', 'back.jpg', 'back.jpg', 'back.jpg']);

						childModel.material = new THREE.MeshStandardMaterial({
							color:"#FFFFFF",
							metalness:0.39,
							roughness:0,
							// map:textureLoader.load('../static/images/dipan.png'),
							// normalMap:textureLoader.load('../static/images/back.jpg'),
							// specularMap:textureLoader.load('../static/dg.jpg'),
							// shininess:100,
							envMap : textureLoader.load('../static/images/dipan.png')
						})
						//环境反射贴图envMap的映射方式，这里用的是一个叫等量矩形投影的映射方法
						// childModel.material.envMap.mapping = THREE.EquirectangularReflectionMapping;
						// childModel.material.envMap = textureCube;
					}
					console.log('[模型]',model)
					model.position.set(0,0,0)
					ob.add(model) 
					// var axishelper = new THREE.AxisHelper(5) // 创建坐标系
					// ob.add(axishelper) // ob类中添加坐标系
					scene.add(ob);
					//调用动画
					this.animate();
			    }, undefined, function (e) {
			      console.error('[模型加载错误]',e);
			    });
				
			},
			animate(){
				ob.rotateY(Math.PI/-720);
				this.animationId = requestAnimationFrame(this.animate);
				renderer.render(scene, camera);
			},
		},
		destroyed(){
			renderer.dispose()
			scene.dispose()
			camera = null
			scene = null
			renderer = null
			ob = null
			cancelAnimationFrame(this.animationId)
			requestAnimationFrame = null
			
		},
		watch:{
			thumb(val){
				console.log('[监听]',val)
				this.modelInit()
			}
		}
	}
</script>

<style lang="scss" scoped>
	.model {
		position: relative;
		canvas{
			width: 100%;
			height: 516rpx;
		}
		.loading{
			display: flex;
			flex-direction: column;
			justify-content: center;
			align-items: center;
			width: 100%;
			height: 516rpx;
			color: #FFFFFF;
			position:absolute;
			left: 0;
			top: 0;
			font-size: 24rpx;
		}
	}
</style>
